package com.moro.lisp.typedefine;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.moro.lisp.JLispData;
import com.moro.lisp.JLispFunctionName;
import com.moro.lisp.JLispMacroName;
import com.moro.lisp.JLispType;
import com.moro.lisp.os.Terminal;
import com.moro.lisp.tools.FunctionPool;
import com.moro.lisp.tools.MacroPool;
import com.moro.lisp.tools.SymbolPool;
import com.moro.lisp.typedefine.Error;

public class Cons {//Cons对.类型(一般意义上是列表)，注意nil不是列表是原子
	
	public static boolean allowLambda = false;
	/*
	 * 这个字段存储的是这个Cons对的第一个值，通常情况下是原子
	 */
	public JLispData val;
	
	
	/*
	 * 这个字段存储的是Cons对的另一个值，通常情况下也是Cons对
	 */
	public JLispData another;
	
	
	/*
	 * 这个字段用来缓存该列表的长度，避免需要用到长度的时候每次都重新调用getConsLength方法，注意在对列表作破坏性地修改时都要刷新长度值，调用getConsLength方法的同时也刷新了长度值
	 */
	private int length;//在构造方法里需要给该length值赋值-1，表示该字段还没有缓存进新的值
	
	/*
	 * 这个字段表示该列表是不是作为像let宏中的赋值列表
	 */
	public boolean isLetArgs;
	
	
	/*
	 * 这个字段表示该列表是不是作为像do宏中的赋值列表
	 */
	public boolean isDoArgs;
	
	//int point;
	
	public boolean isFunExpr; // 表示是否为函数列表(可直接调用的列表)
	
	
	public JLispData self;
	
	public Cons(JLispData val, JLispData another) {
		this.val = val;
		
		this.another = another;
		
		this.length = -1;//-1表示该字段还没有缓存进新的列表长度值
		
		this.isLetArgs = false;
		
		this.isDoArgs = false;
		
		this.isFunExpr = Cons.allowLambda;
		
		this.self = null;
		
	}
	public Cons(JLispData[] items,Atom atom) {//根据元素数组创建一个列表
		if(items.length == 1) {
			this.val = items[0];
			this.another = new JLispData(atom, JLispType.ATOM);
			this.length = -1;
			this.isLetArgs = false;
			this.isDoArgs = false;
			this.isFunExpr = Cons.allowLambda;
			this.self = null;
		}else {
			this.val = items[0];
			this.another = new JLispData(new Cons(getArrWithoutStart(items), atom),JLispType.CONS);
			this.length = -1;
			this.isLetArgs = false;
			this.isDoArgs = false;
			this.isFunExpr = Cons.allowLambda;
			this.self = null;
		}
	}
	private JLispData[] getArrWithoutStart(JLispData[] items) {
		JLispData[] returnItems = new JLispData[items.length - 1];
		for(int i = 0;i < returnItems.length;i++) {
			returnItems[i] = items[i + 1];
		}
		return returnItems;
	}
	public JLispData eval(SymbolPool symbolPool, FunctionPool functionPool, MacroPool macroPool) {//对列表求值需要符号池和函数池
		/*
		 * 对一个列表求值的步骤
		 * 1.确定这个列表是一个正规列表还是点对列表(特殊列表)如：（A B C . D）,如果是点对列表则返回Error
		 * 2.先确定第一个元素是不是原子，不是返回error
		 * 3.确定这个原子的函数值是不是null，是的话返回error
		 * 4.确定函数值是函数还是宏后面分别进行对应的处理
		 * 5.如果是函数的话
		 * 判断是不是if，or，and这三个逻辑函数（为什么要特殊对待这三个函数，因为这三个函数属于逻辑处理，在一些情况下可以不用对参数全部求完值）
		 */
		if(isSpecialCons()) {//判断是不是特殊列表，是的话返回错误
			return new JLispData(new Error("Can not eval the special list"), JLispType.ERROR);
		}
		if(!(JLispType.ATOM == this.val.type) && !(JLispType.FUNCTION == this.val.type) && !(JLispType.MACRO == this.val.type) && !(JLispType.CONS == this.val.type)) {//判断第一个元素是不是原子，函数或宏，不是的话返回错误
			return new JLispData(new Error("The data of the type not the Atom has not the function value"), JLispType.ERROR);
		}
		JLispData functionOrMacro;
		JLispData self = null;
		if(JLispType.ATOM == this.val.type) {
			Atom a = (Atom)(this.val.data);
			functionOrMacro = a.functionEval();
			if(null == functionOrMacro) {//判断函数值有没有函数或宏，没有的话返回错误
				return new JLispData(new Error("The Atom \""+a.name+"\" has not function value or macro value"), JLispType.ERROR);
			}
		}else if(JLispType.CONS== this.val.type) {
			Cons asFunCons = (Cons)(this.val.data);
			if(!asFunCons.isFunExpr) {
				return new JLispData(new Error("The data of the type not the Atom has not the function value"), JLispType.ERROR);
			}
			functionOrMacro = this.val.eval(symbolPool, functionPool, macroPool);
			self = asFunCons.self;
		}else {
			functionOrMacro = this.val;
		}
		

		if(JLispType.FUNCTION == functionOrMacro.type) {//如果是函数的话
			Function function = (Function)(functionOrMacro.data);
			if(null != self) {
				this.another = new JLispData(new Cons(self, this.another), JLispType.CONS);
			}
			if(JLispFunctionName.IF == function.functionName) {//如果这个函数是if的话
				/*
				 * 判断列表长度，如果小于3返回错误
				 */
				if(getLength() < 3) {
					return new JLispData(new Error("The function \"if\" expected at least 2 args"),JLispType.ERROR);
				}
				/*
				 * if函数的第一个参数是条件，必须求值
				 */
				JLispData arg1 = getItemById(1).eval(symbolPool, functionPool, macroPool);//arg1表示对第一个元素求值的结果，只要结果不为原子nil且不为错误，则代表真
				
				if(JLispType.ERROR == arg1.type) {//如果第一个条件参数求值为错误，则返回该错误
					return arg1;
				}
				
				if(JLispType.ATOM == arg1.type) {
					Atom atom = (Atom)(arg1.data);
					if("nil".equalsIgnoreCase(atom.name)) {//为假，返回第三个参数的eval
						if(getLength() >= 4) {//如果该列表长度为4，则代表有第三个参数
							JLispData executeAns = getItemById(3).eval(symbolPool, functionPool, macroPool);
//							暂时不将逻辑控制类函数添加进调用栈
//							functionPool.into(functionOrMacro, this.val);
//							functionPool.outfrom(functionOrMacro, executeAns, this.val);
							return executeAns;
						}else {//如果该列表长度不为4，则代表没有第三个参数
							JLispData executeAns = new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);//
//							functionPool.into(functionOrMacro, this.val);
//							functionPool.outfrom(functionOrMacro, executeAns, this.val);
							return executeAns;
						}
					}else {//为真，返回第二个参数的求值
						JLispData executeAns = getItemById(2).eval(symbolPool, functionPool, macroPool);
//						functionPool.into(functionOrMacro, this.val);
//						functionPool.outfrom(functionOrMacro, executeAns, this.val);
						return executeAns;
					}
				}else {//为真，返回第二个参数的求值
					JLispData executeAns = getItemById(2).eval(symbolPool, functionPool, macroPool);
//					functionPool.into(functionOrMacro, this.val);
//					functionPool.outfrom(functionOrMacro, executeAns, this.val);
					return executeAns;
				}
			}else if(JLispFunctionName.OR == function.functionName) {//如果这个函数是or的话,返回第一个不为nil的值
				if(getLength() == 1) {//当列表长度为1时代表没有参数，返回nil原子
					JLispData executeAns = new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
//					暂时不将逻辑控制类函数添加进调用栈
//					functionPool.into(functionOrMacro, this.val);
//					functionPool.outfrom(functionOrMacro, executeAns, this.val);
					return executeAns;
				}
				for(int i = 1;i < getLength();i++) {
					JLispData returnValue = getItemById(i).eval(symbolPool, functionPool, macroPool);
					
					if(i == getLength() - 1) {//如果已经到了最后一个参数，则直接返回
						JLispData executeAns = returnValue;
//						functionPool.into(functionOrMacro, this.val);
//						functionPool.outfrom(functionOrMacro, executeAns, this.val);
						return executeAns;
					}
					
					if(JLispType.ERROR == returnValue.type) {//如果某一个参数求值为错误，则直接返回这个错误
						return returnValue;
					}
					
					
					if(!(JLispType.ATOM == returnValue.type)) {//如果该参数的返回值不为原子，那肯定代表真，则返回这个返回值
						JLispData executeAns = returnValue;
//						functionPool.into(functionOrMacro, this.val);
//						functionPool.outfrom(functionOrMacro, executeAns, this.val);
						return executeAns;
					}else {
						Atom atom = (Atom)(returnValue.data);
						if(!("nil".equalsIgnoreCase(atom.name))) {//如果这个原子不是nil的话，则返回它
							JLispData executeAns = returnValue;
//							functionPool.into(functionOrMacro, this.val);
//							functionPool.outfrom(functionOrMacro, executeAns, this.val);
							return executeAns;
						}
					}
				}
			}else if(JLispFunctionName.AND == function.functionName) {//如果这个函数是and的话,返回第一个为nil的值
				if(getLength() == 1) {//当列表长度为1时代表没有参数，返回t原子
					JLispData executeAns = new JLispData(symbolPool.getSymbolByString("t"), JLispType.ATOM);
//					暂时不将逻辑控制类函数添加进调用栈
//					functionPool.into(functionOrMacro, this.val);
//					functionPool.outfrom(functionOrMacro, executeAns, this.val);
					return executeAns;
				}
				for(int i = 1;i < getLength();i++) {
					JLispData returnValue = getItemById(i).eval(symbolPool, functionPool, macroPool);
					
					if(i == getLength() - 1) {//如果已经到了最后一个参数，则直接返回
						JLispData executeAns = returnValue;
//						functionPool.into(functionOrMacro, this.val);
//						functionPool.outfrom(functionOrMacro, executeAns, this.val);
						return executeAns;
					}
					
					if(JLispType.ERROR == returnValue.type) {//如果某一个参数求值为错误，则直接返回这个错误
						return returnValue;
					}
					
					
					if(JLispType.ATOM == returnValue.type) {//如果该参数的返回值为原子，则判断是不是nil原子，是的话返回，不是的话继续
						Atom atom = (Atom)(returnValue.data);
						if("nil".equalsIgnoreCase(atom.name)) {//如果这个原子是nil的话，则返回它
							JLispData executeAns = returnValue;
//							functionPool.into(functionOrMacro, this.val);
//							functionPool.outfrom(functionOrMacro, executeAns, this.val);
							return executeAns;
						}
					}
				}
			}else if(JLispFunctionName.LIST == function.functionName) {//如果这个函数是list的话,需要特殊处理parselist函数
				//JLispData[] args = new JLispData[getLength() - 1];
				List<JLispData> argslist = new ArrayList<JLispData>();
				
				for(int i = 1;i < getLength();i++) {
					JLispData argitem = getItemById(i);
					if(isParseList(argitem)) {
						JLispData orCons = ((Cons)(argitem.data)).getItemById(1).eval(symbolPool, functionPool, macroPool);
						if(JLispType.CONS != orCons.type) {
							if(JLispType.ERROR == orCons.type) {
								return orCons;
							}
							//argslist.add(orCons);
						}else {
							Cons parselist = (Cons)(orCons.data);
							for(int index = 0;index < parselist.getLength();index++) {
								JLispData item = parselist.getItemById(index);
								if(JLispType.ERROR == item.type) {
									return item;
								}
								argslist.add(item);
							}
						}
						continue;
					}
					JLispData tempArg = argitem.eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == tempArg.type) {//如果某一个参数列表求值为错误类型，则该列表同样返回该错误
						
						return tempArg;
					}
					argslist.add(tempArg);
				}
				JLispData[] args = new JLispData[argslist.size()];
				for(int index = 0;index < args.length;index++) {
					
					args[index] = argslist.get(index);
				}
				functionPool.into(args, functionOrMacro, this.val);
				JLispData executeAns = function.execute(args, symbolPool, functionPool, macroPool);//最后返回将参数值传入函数中的执行结果
				functionPool.outfrom(functionOrMacro, executeAns, this.val);
				return executeAns;
				//如果为parselist函数
			}else if(JLispFunctionName.TIME == function.functionName) {
				long executeStart = new Date().getTime();
				JLispData ans = new JLispData(symbolPool.getSymbolByString("" + executeStart), JLispType.ATOM);
				boolean needLog = false;
				JLispData[] args = new JLispData[getLength() - 1];
				for(int i = 1;i < getLength();i++) {
					ans = getItemById(i).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == ans.type) {
						return ans;
					}
					args[i - 1] = ans;
					needLog = true;
				}
				functionPool.into(args, functionOrMacro, this.val);
				if(needLog)
				Terminal.makeMessage("Execute time:"+(new Date().getTime() - executeStart)+"millisec");
				functionPool.outfrom(functionOrMacro, ans, this.val);
				return ans;
			}else if(JLispFunctionName.APPLY == function.functionName) {
				if(getLength() != 3) {
					return new JLispData(new Error("The function \"apply\" expected 2 args, but found "+(getLength() - 1)+" arg"), JLispType.ERROR);
				}
				JLispData isFunctionOrMacro = getItemById(1).eval(symbolPool, functionPool, macroPool);
				if((JLispType.FUNCTION != isFunctionOrMacro.type) && (JLispType.MACRO != isFunctionOrMacro.type)) {
					return new JLispData(new Error("The function \"apply\" needs a function or a macro to execute"), JLispType.ERROR);
				}
				//修复apply函数 (apply fn'add '((add 1 2) 3 4))返回10的bug  也就是列表中的元素不应该被求值，而是应该直接传入给定函数，解决办法为列表中的每个元素前加一个quote使其对自身求值
				JLispData arglist = getItemById(2).eval(symbolPool, functionPool, macroPool);
				JLispData[] args = new JLispData[2];
				args[0] = isFunctionOrMacro;
				args[1] = arglist;
				if(JLispType.CONS == arglist.type) {
					args[1] = new JLispData(clone((Cons)(arglist.data)), JLispType.CONS);
					Cons argcons = (Cons)(arglist.data);
					for(int i = 0;i < argcons.getLength();i++) {
						argcons.setItemById(i, new JLispData(new Cons(new JLispData[]{
								new JLispData(symbolPool.getSymbolByString("quote"), JLispType.ATOM), argcons.getItemById(i)},
								symbolPool.getSymbolByString("nil")),
								JLispType.CONS));
					}
				}
				if(JLispType.ERROR == arglist.type) {
					return arglist;
				}
				functionPool.into(args, functionOrMacro, this.val);
				JLispData executeAns = new JLispData(new Cons(isFunctionOrMacro, arglist), JLispType.CONS).eval(symbolPool, functionPool, macroPool);
				functionPool.outfrom(functionOrMacro, executeAns, this.val);
				return executeAns;
			}else if(JLispFunctionName.FUNCALL == function.functionName) {
				if(getLength() < 2) {
					return new JLispData(new Error("The function \"funcall\" expected more than 1 args, but found "+(getLength() - 1)+" arg"), JLispType.ERROR);
				}
				JLispData isFunctionOrMacro = getItemById(1).eval(symbolPool, functionPool, macroPool);
				if((JLispType.FUNCTION != isFunctionOrMacro.type) && (JLispType.MACRO != isFunctionOrMacro.type)) {
					return new JLispData(new Error("The function \"funcall\" needs a function or a macro to execute"), JLispType.ERROR);
				}
				JLispData[] args = new JLispData[getLength() - 1];
				JLispData[] _args = new JLispData[getLength() - 2];
				args[0] = isFunctionOrMacro;
				for(int i = 2;i < getLength();i++) {
					JLispData tempArg = getItemById(i).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == tempArg.type) {//如果某一个参数列表求值为错误类型，则该列表同样返回该错误
						return tempArg;
					}
					args[i - 1] = tempArg;
					_args[i - 2] = tempArg;
				}
				
				JLispData arglist = null;
				if(0 != _args.length) {
					arglist = new JLispData(new Cons(_args, symbolPool.getSymbolByString("nil")), JLispType.CONS);
				}else {
					arglist = new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
				}
				
				if(JLispType.CONS == arglist.type) {
					Cons argcons = (Cons)(arglist.data);
					for(int i = 0;i < argcons.getLength();i++) {
						argcons.setItemById(i, new JLispData(new Cons(new JLispData[]{
								new JLispData(symbolPool.getSymbolByString("quote"), JLispType.ATOM), argcons.getItemById(i)},
								symbolPool.getSymbolByString("nil")),
								JLispType.CONS));
					}
				}
				
				functionPool.into(args, functionOrMacro, this.val);
//				JLispData executeAns = new JLispData(new Cons(isFunctionOrMacro, ((Cons)(this.another.data)).another), JLispType.CONS).eval(symbolPool, functionPool, macroPool);
				JLispData executeAns = new JLispData(new Cons(isFunctionOrMacro, arglist), JLispType.CONS).eval(symbolPool, functionPool, macroPool);
				functionPool.outfrom(functionOrMacro, executeAns, this.val);
				return executeAns;
			}else {//除了if，and，or这三个函数需要看情况对参数求值外，其余所有的函数都是对所有的参数进行求值，然后再代入函数执行
				//List<JLispData> argsList
				JLispData[] args = new JLispData[getLength() - 1];
				for(int i = 1;i < getLength();i++) {
					JLispData tempArg = getItemById(i).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == tempArg.type) {//如果某一个参数列表求值为错误类型，则该列表同样返回该错误
						return tempArg;
					}
					args[i - 1] = tempArg;
				}
				functionPool.into(args, functionOrMacro, this.val);
				JLispData executeAns = function.execute(args, symbolPool, functionPool, macroPool);//最后返回将参数值传入函数中的执行结果
				functionPool.outfrom(functionOrMacro, executeAns, this.val);
				return executeAns;
			}
		}else if(JLispType.MACRO == functionOrMacro.type) {//如果是宏的话
			Macro macro = (Macro)(functionOrMacro.data);
			if(JLispMacroName.DEFUN == macro.macroName) {
				/*
				 * 首先检查整个列表的长度，如果小于3则返回错误
				 */
				if(getLength() < 3) {
					return new JLispData(new Error("The macro \"DEFUN\" expected at least 3 args"), JLispType.ERROR);
				}
				/*
				 * 然后检查第一个参数是否为原子，不是原子或者为特殊原子的话返回错误
				 */
				Atom atom = null;
				if(getItemById(1).type != JLispType.ATOM ||
						((Atom)(getItemById(1).data)).symbolValues == null) {
					return new JLispData(new Error("The macro \"DEFUN\" needs a right symbol as the function name"), JLispType.ERROR);
				}else {
					atom = (Atom)(getItemById(1).data);
				}
				
				/*
				 * 检查第二个参数是不是列表
				 */
				Cons arg = null;
				Atom nil = null;
				if(getItemById(2).type != JLispType.CONS) {
					if(getItemById(2).type != JLispType.ATOM) {//如果不是列表也不是原子则返回错误
						return new JLispData(new Error("The macro \"DEFUN\" needs a list as the function args"), JLispType.ERROR);
					}else {//如果是原子再判断是不是nil原子，不是同样返回错误
						
						if(!"nil".equalsIgnoreCase(((Atom)(getItemById(2).data)).name)) {
							return new JLispData(new Error("The macro \"DEFUN\" needs a list as the function args"), JLispType.ERROR);
						}else {
							nil = (Atom)(getItemById(2).data);
						}
					}
				}
				/*
				 * 判断第二个参数是不是符合规矩的列表
				 */
				if(getItemById(2).type == JLispType.CONS) {//只需要判断Cons的情况，因为如果是原子的话肯定是nil原子，上面已经检测			
					if(!canBeArgs(((Cons)(getItemById(2).data)), symbolPool.getSymbolByString("&rest"))) {//如果不能，返回错误
						return new JLispData(new Error("The macro \"DEFUN\" needs a right list as the function args"), JLispType.ERROR);
					}else {
						arg = (Cons)(getItemById(2).data);
					}
				}
				
				/*
				 * 如果列表长度为3，代表没有函数体
				 */
				if(getLength() == 3) {
					if(null == arg && null != nil) {
						return new JLispData(functionPool.getFunctionByFunctionName(JLispFunctionName.CUSTOMIZE, atom, nil, null, null),
								JLispType.FUNCTION);
					}else if(null != arg && null == nil) {
						return new JLispData(functionPool.getFunctionByFunctionName(JLispFunctionName.CUSTOMIZE, atom, arg, null, null),
								JLispType.FUNCTION);
					}else {
						return new JLispData(new Error("Unknown Error!"), JLispType.ERROR);
					}
				}
				//如果有函数体，则先生成函数，再检测闭包
				//暂时不对内置宏进行调用栈的添加，意义不大
				//functionPool.into(functionOrMacro);
				List<JLispData> functionBodys = new ArrayList<JLispData>();
				for(int i = 3;i < this.getLength();i++) {
					functionBodys.add(this.getItemById(i));
				}
				Function function = null;
				if(null == arg && null != nil) {
					function = functionPool.getFunctionByFunctionName(JLispFunctionName.CUSTOMIZE, atom, nil, functionBodys, null);
				}else if(null != arg && null == nil) {
					function = functionPool.getFunctionByFunctionName(JLispFunctionName.CUSTOMIZE, atom, arg, functionBodys, null);
				}else {
					
					JLispData executeAns = new JLispData(new Error("Unknown Error!"), JLispType.ERROR);
					//functionPool.outfrom(functionOrMacro, executeAns);
					return executeAns;
				}
				
				if(null == arg && null != nil) {
					function.closure = getClosure(new JLispData(nil, JLispType.ATOM), functionBodys, symbolPool, new JLispData(function, JLispType.FUNCTION));
				}else if(null != arg && null == nil) {
					function.closure = getClosure(new JLispData(arg, JLispType.CONS), functionBodys, symbolPool, new JLispData(function, JLispType.FUNCTION));
				}
				JLispData executeAns = new JLispData(function, JLispType.FUNCTION);
				//functionPool.outfrom(functionOrMacro, executeAns);
				return executeAns;
				
			}else if(JLispMacroName.DEFMACRO == macro.macroName) {
				/*
				 * 首先检查整个列表的长度，如果小于3则返回错误
				 */
				if(getLength() < 3) {
					return new JLispData(new Error("The macro \"DEFMACRO\" expected at least 3 args"), JLispType.ERROR);
				}
				/*
				 * 然后检查第一个参数是否为原子，不是原子或者为特殊原子的话返回错误
				 */
				Atom atom = null;
				if(getItemById(1).type != JLispType.ATOM ||
						((Atom)(getItemById(1).data)).symbolValues == null) {
					return new JLispData(new Error("The macro \"DEFMACRO\" needs a right symbol as the macro name"), JLispType.ERROR);
				}else {
					atom = (Atom)(getItemById(1).data);
				}
				
				/*
				 * 检查第二个参数是不是列表
				 */
				Cons arg = null;
				Atom nil = null;
				if(getItemById(2).type != JLispType.CONS) {
					if(getItemById(2).type != JLispType.ATOM) {//如果不是列表也不是原子则返回错误
						return new JLispData(new Error("The macro \"DEFMACRO\" needs a list as the macro args"), JLispType.ERROR);
					}else {//如果是原子再判断是不是nil原子，不是同样返回错误
						
						if(!"nil".equalsIgnoreCase(((Atom)(getItemById(2).data)).name)) {
							return new JLispData(new Error("The macro \"DEFMACRO\" needs a list as the macro args"), JLispType.ERROR);
						}else {
							nil = (Atom)(getItemById(2).data);
						}
					}
				}
				/*
				 * 判断第二个参数是不是符合规矩的列表
				 */
				if(getItemById(2).type == JLispType.CONS) {//只需要判断Cons的情况，因为如果是原子的话肯定是nil原子，上面已经检测			
					if(!canBeArgs(((Cons)(getItemById(2).data)), symbolPool.getSymbolByString("&rest"))) {//如果不能，返回错误
						return new JLispData(new Error("The macro \"DEFMACRO\" needs a right list as the macro args"), JLispType.ERROR);
					}else {
						arg = (Cons)(getItemById(2).data);
					}
				}
				
				/*
				 * 如果列表长度为3，代表没有宏函数体
				 */
				if(getLength() == 3) {
					if(null == arg && null != nil) {
						return new JLispData(macroPool.getMacroByMacroName(JLispMacroName.CUSTOMIZE, atom, nil, null, null),
								JLispType.MACRO);
					}else if(null != arg && null == nil) {
						return new JLispData(macroPool.getMacroByMacroName(JLispMacroName.CUSTOMIZE, atom, arg, null, null),
								JLispType.MACRO);
					}else {
						return new JLispData(new Error("Unknown Error!"), JLispType.ERROR);
					}
				}
				//如果有宏函数体，则先生成宏函数，再检测闭包
				//暂时不对内置宏进行调用栈的添加，意义不大
				//functionPool.into(functionOrMacro);
				List<JLispData> macroBodys = new ArrayList<JLispData>();
				for(int i = 3;i < this.getLength();i++) {
					macroBodys.add(this.getItemById(i));
				}
				Macro _macro = null;
				if(null == arg && null != nil) {
					_macro = macroPool.getMacroByMacroName(JLispMacroName.CUSTOMIZE, atom, nil, macroBodys, null);
				}else if(null != arg && null == nil) {
					
					_macro = macroPool.getMacroByMacroName(JLispMacroName.CUSTOMIZE, atom, arg, macroBodys, null);
				}else {
					JLispData executeAns = new JLispData(new Error("Unknown Error!"), JLispType.ERROR);
					//functionPool.outfrom(functionOrMacro, executeAns);
					return executeAns;
				}
				
				if(null == arg && null != nil) {
					_macro.closure = getClosure(new JLispData(nil, JLispType.ATOM), macroBodys, symbolPool, new JLispData(_macro, JLispType.MACRO));
				}else if(null != arg && null == nil) {
					_macro.closure = getClosure(new JLispData(arg, JLispType.CONS), macroBodys, symbolPool, new JLispData(_macro, JLispType.MACRO));
				}
				JLispData executeAns = new JLispData(_macro, JLispType.MACRO);
				//functionPool.outfrom(functionOrMacro, executeAns);
				return executeAns;
			}else if(JLispMacroName.SETQ == macro.macroName) {
				if(getLength() == 1) {
					return new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
				}
				if(getLength() % 2 == 0) {
					return new JLispData(new Error("The macro \"setq\" needs even number args"), JLispType.ERROR);
				}
				JLispData returnValue = null;
				for(int i = 1;i < getLength() - 1;i += 2) {
					if(JLispType.ATOM != getItemById(i).type) {
						new Error("The variable can only be atom");
						continue;
					}
					Atom var = (Atom)(getItemById(i).data);
					if(null == var.symbolValues) {
						new Error("The variable can not be the special atom");
						continue;
					}
					JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == value.type) {
						continue;
					}
					if(var.symbolValues.getSize() == 0) {
						var.setValue(value);
					}else {
						var.resetValue(value);
					}
					returnValue = value;
					//returnValue = var.eval();
				}
				if(null == returnValue) {
					return new JLispData(new Error("Failed to set value"), JLispType.ERROR);
				}else {
					return returnValue;
				}
			}else if(JLispMacroName.SETF == macro.macroName) {
				if(getLength() == 1) {
					return new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
				}
				if(getLength() % 2 == 0) {
					return new JLispData(new Error("The macro \"setf\" needs even number args"), JLispType.ERROR);
				}
				JLispData returnValue = null;
				for(int i = 1;i < getLength() - 1;i += 2) {
					if(JLispType.ATOM != getItemById(i).type) {
						if(JLispType.CONS != getItemById(i).type) {
							new Error("The variable can only be atom or settable cons");
							continue;
						}else {
							Cons varCons = (Cons)(getItemById(i).data);
							JLispData howGet = varCons.getItemById(0);
							if(JLispType.ATOM != howGet.type) {
								new Error("Unsettable cons can not be the left value of set expr");
								continue;
							}else {
								Atom isFun = (Atom)(howGet.data);
								if(null == isFun.functionEval()) {
									new Error("Unsettable cons can not be the left value of set expr");
									continue;
								}else {
									JLispData funOrMac = isFun.functionEval();
									if(JLispType.MACRO == funOrMac.type) {
										//执行宏翻译，再检测看是不是可设置的列表
										Macro mac = (Macro)(funOrMac.data);
										if(JLispMacroName.CUSTOMIZE != mac.macroName) {
											new Error("Unsettable macro cons can not be the left value of set expr");
											continue;
										}
										JLispData[] args = new JLispData[varCons.getLength() - 1];
										for(int p = 1;p < varCons.getLength();p++) {
											args[p - 1] = varCons.getItemById(p);
										}
										JLispData replaceExpr = mac.execute(args, symbolPool, functionPool, macroPool);
										setItemById(i, replaceExpr);
										i -= 2;
										continue;
									}else {
										Function fun = (Function)(funOrMac.data);
										if(JLispFunctionName.CAR == fun.functionName) {
											if(varCons.getLength() != 2) {
												new Error("The function \"car\" expected 1 arg, but found "+(varCons.getLength() - 1)+" arg");
												continue;
											}
											JLispData consToSet = varCons.getItemById(1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.CONS != consToSet.type) {
												new Error("The function \"car\" needs a list to be the arg");
												continue;
											}
											JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ERROR == value.type) {
												continue;
											}
											((Cons)(consToSet.data)).val = value;
											returnValue = value;
											continue;
										}else if(JLispFunctionName.CDR == fun.functionName) {
											if(varCons.getLength() != 2) {
												new Error("The function \"cdr\" expected 1 arg, but found "+(varCons.getLength() - 1)+" arg");
												continue;
											}
											JLispData consToSet = varCons.getItemById(1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.CONS != consToSet.type) {
												new Error("The function \"cdr\" needs a list to be the arg");
												continue;
											}
											JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ERROR == value.type) {
												continue;
											}
											((Cons)(consToSet.data)).another = value;
											((Cons)(consToSet.data)).flushConsLength();
											returnValue = value;
											continue;
										}else if(JLispFunctionName.NTH == fun.functionName) {
											if(varCons.getLength() != 3) {
												new Error("The function \"nth\" expected 2 args, but found "+(varCons.getLength() - 1)+" arg");
												continue;
											}
											JLispData isNum = varCons.getItemById(1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ATOM != isNum.type) {
												new Error("The function \"nth\" needs an number to be the index of list");
												continue;
											}
											Atom atom = (Atom)(isNum.data);
											if(!atom.isNumber) {
												new Error("The function \"nth\" needs an number to be the index of list");
												continue;
											}
											int index = (int)(Double.valueOf(atom.name).doubleValue());
											JLispData isList = varCons.getItemById(2).eval(symbolPool, functionPool, macroPool);
											if(JLispType.CONS != isList.type) {
												new Error("The function \"nth\" needs a list");
												continue;
											}
											Cons list = (Cons)(isList.data);
											if(index >= list.getLength()) {
												new Error("Can not set the item of this cons,Because of IndexOutOfBoundsError");
												continue;
											}
											JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ERROR == value.type) {
												continue;
											}
											list.setItemById(index, value);
											returnValue = value;
											continue;
										}else if(JLispFunctionName.SYMBOLVALUE == fun.functionName) {
											if(varCons.getLength() != 2) {
												new Error("The function \"symbolvalue\" expected 1 arg, but found "+(varCons.getLength() - 1)+" arg");
												continue;
											}
											JLispData isAtom = varCons.getItemById(1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ATOM != isAtom.type) {
												new Error("The function \"symbolvalue\" expected data of Atom, but found other type");
												continue;
											}
											Atom atom = (Atom)(isAtom.data);
											if(null == atom.symbolValues) {
												new Error("Can not set the special atom's general value");
												continue;
											}
											JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ERROR == value.type) {
												continue;
											}
											if(atom.symbolValues.getSize() == 0) {
												atom.setValue(value);
											}else {
												atom.resetValue(value);
											}
											returnValue = value;
											continue;
										}else if(JLispFunctionName.SYMBOLFUNCTION == fun.functionName) {
											if(varCons.getLength() != 2) {
												new Error("The function \"symbolfunction\" expected 1 arg, but found "+(varCons.getLength() - 1)+" arg");
												continue;
											}
											JLispData isAtom = varCons.getItemById(1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ATOM != isAtom.type) {
												new Error("The function \"symbolfunction\" expected data of Atom, but found other type");
												continue;
											}
											Atom atom = (Atom)(isAtom.data);
											if(null == atom.symbolValues) {
												new Error("Can not set the special atom's function value");
												continue;
											}
											JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
											if(JLispType.ERROR == value.type) {
												continue;
											}
											if(JLispType.FUNCTION != value.type && JLispType.MACRO != value.type) {
												new Error("Can not set the atom's function value to the data expect the function or macro");
												continue;
											}
											atom.setFunctionVal(value);
											returnValue = value;
											continue;
										}else {
											new Error("Unsettable cons can not be the left value of set expr");
											continue;
										}
									}
								}
							}
						}	
					}
					Atom var = (Atom)(getItemById(i).data);
					if(null == var.symbolValues) {
						new Error("The variable can not be the special atom");
						continue;
					}
					JLispData value = getItemById(i + 1).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == value.type) {
						continue;
					}
					if(var.symbolValues.getSize() == 0) {
						var.setValue(value);
					}else {
						var.resetValue(value);
					}
					returnValue = value;
					//returnValue = var.eval();
				}
				if(null == returnValue) {
					return new JLispData(new Error("Failed to set value"), JLispType.ERROR);
				}else {
					return returnValue;
				}
			}else if(JLispMacroName.DO == macro.macroName) {
				if(getLength() < 3) {
					return new JLispData(new Error("The macro \"do\" needs at least 3 args"), JLispType.ERROR);
				}
				if(JLispType.CONS != getItemById(2).type) {
					return new JLispData(new Error("The macro \"do\" needs a list to be exit clause"), JLispType.ERROR);
				}
				JLispData nilOrArgs = getItemById(1);
				List<Cons> localVarList = new ArrayList<Cons>();
				if(JLispType.ATOM == nilOrArgs.type) {
					if(!"nil".equalsIgnoreCase(((Atom)(getItemById(1).data)).name)) {
						new Error("The macro \"do\" needs a list(\"nil\" or \"((var value increase) ...)\") to declare local variables");
					}
				}
				if(JLispType.CONS == nilOrArgs.type) {
					Cons args = (Cons)(nilOrArgs.data);
					for(int i = 0;i < args.getLength();i++) {
						if(JLispType.CONS != args.getItemById(i).type) {
							new Error("The variable list should not have the data except the cons");
						}else {
							Cons argList = (Cons)(args.getItemById(i).data);
							if(JLispType.ATOM != argList.getItemById(0).type) {
								new Error("The variable should be an atom");
								continue;
							}
							Atom var = (Atom)(argList.getItemById(0).data);
							if(null != var.symbolValues) {
								localVarList.add(argList);
							}
							
						
						}
					}
				}
				//初始化
				for(Cons argList:localVarList) {
					if(argList.getLength() == 1) {
						pushValueForDo((Atom)(argList.getItemById(0).data), new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM));
					}else {
						JLispData value = argList.getItemById(1).eval(symbolPool, functionPool, macroPool);
						if(JLispType.ERROR == value.type) {
							pushValueForDo((Atom)(argList.getItemById(0).data), new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM));
						}else {
							pushValueForDo((Atom)(argList.getItemById(0).data), value);
						}
					}
				}
				//循环
				while(true) {
					Cons conditionList = (Cons)(getItemById(2).data);
					JLispData condition = conditionList.getItemById(0).eval(symbolPool, functionPool, macroPool);
					if(JLispType.ERROR == condition.type) {//如果条件求值为错误则直接返回
						popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
						return condition;
					}
					//如果条件求值不为原子，或者是原子但不是原子nil，则表明为真，返回后面的值,如果后面没有元素，则就返回条件的求值，这一点和CommonLisp的语法不一样
					//CommonLisp中返回原子nil
					
					//如果不为原子的情况
					if(JLispType.ATOM != condition.type) {
						JLispData returnValue = condition;
						for(int i = 1;i < conditionList.getLength();i++) {//直接从第二个元素开始求值，如果没有第二个元素，则循环不会进行
							returnValue = conditionList.getItemById(i).eval(symbolPool, functionPool, macroPool);
							if(JLispType.ERROR == returnValue.type) {//如果有一个求值为错误，则立马返回这个错误
								popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
								return returnValue;
							}
						}
						popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
						return returnValue;
					}
					
					//如果为原子但不为原子nil的情况
					if(JLispType.ATOM == condition.type) {
						if(!"nil".equalsIgnoreCase(((Atom)(condition.data)).name)) {
							JLispData returnValue = condition;
							for(int i = 1;i < conditionList.getLength();i++) {//直接从第二个元素开始求值，如果没有第二个元素，则循环不会进行
								returnValue = conditionList.getItemById(i).eval(symbolPool, functionPool, macroPool);
								if(JLispType.ERROR == returnValue.type) {//如果有一个求值为错误，则立马返回这个错误
									popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
									return returnValue;
								}
							}
							popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
							return returnValue;
						}
					}
					//执行循环体
					if(getLength() > 3) {
						for(int i = 3;i < getLength();i++) {
							JLispData isError = getItemById(i).eval(symbolPool, functionPool, macroPool);
							if(JLispType.ERROR == isError.type) {
								popValueForDo(localVarList);//从do宏返回一定要记得将局部变量出栈
								return isError;
							}
						}
					}
					//System.out.println(((Atom)(symbolPool.getSymbolByString("i").eval().data)).name);
					//重设局部变量
					for(Cons argList:localVarList) {
						
						if(argList.getLength() == 1) {//如果只有变量一个元素，那么重设后肯定还是原子”nil“
							resetValueForDo((Atom)(argList.getItemById(0).data), new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM));
						}else {
							
							JLispData value = null;
							for(int i = 2;i < argList.getLength();i++) {//这里注意一定要从第三个也就是真正的增长变量开始求值，不然会造成每次对初始变量进行重复求值
								
								JLispData tempValue = argList.getItemById(i).eval(symbolPool, functionPool, macroPool);
								if(JLispType.ERROR == tempValue.type) {//如果是错误则继续
									//continue;
									return tempValue;
								}
								value = tempValue;
								
							}
							if(null == value) {//如果要重设的值为null，证明没有要重设的值，此时直接跳过此变量
								continue;
							}
							resetValueForDo((Atom)(argList.getItemById(0).data), value);
						}
					}
				}
			}else if(JLispMacroName.LET == macro.macroName) {
				if(getLength() < 2) {
					return new JLispData(new Error("The macro \"let\" needs at least 3 args"), JLispType.ERROR);
				}
				JLispData nilOrArgs = getItemById(1);
				List<Cons> localVarList = new ArrayList<Cons>();
				if(JLispType.ATOM == nilOrArgs.type) {
					if(!"nil".equalsIgnoreCase(((Atom)(getItemById(1).data)).name)) {
						new Error("The macro \"let\" needs a list(\"nil\" or \"((var value) ...)\") to declare local variables");
					}
				}
				if(JLispType.CONS == nilOrArgs.type) {
					Cons args = (Cons)(nilOrArgs.data);
					for(int i = 0;i < args.getLength();i++) {
						if(JLispType.CONS != args.getItemById(i).type) {
							new Error("The variable list should not have the data except the cons");
						}else {
							Cons argList = (Cons)(args.getItemById(i).data);//提取出具体的变量声明列表
							if(JLispType.ATOM != argList.getItemById(0).type) {//将变量声明列表添加进localVarList的条件是第一个元素必须是原子
								new Error("The variable should be an atom");
								continue;
							}
							Atom var = (Atom)(argList.getItemById(0).data);
							if(null != var.symbolValues) {//然后必须是普通原子
								localVarList.add(argList);
							}
							
						
						}
					}
				}
				//初始化
				for(Cons argList:localVarList) {
					if(argList.getLength() == 1) {
						pushValueForDo((Atom)(argList.getItemById(0).data), new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM));
					}else {
						JLispData value = new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
						for(int i = 1;i < argList.getLength();i++) {
							JLispData tempValue = argList.getItemById(i).eval(symbolPool, functionPool, macroPool);
							if(JLispType.ERROR == tempValue.type) {
								continue;
							}
							value = tempValue;
						}
						pushValueForDo((Atom)(argList.getItemById(0).data), value);
					}
				}
				if(getLength() > 2) {
					JLispData returnValue = null;
					for(int i = 2;i < getLength();i++) {
						JLispData tempValue = getItemById(i).eval(symbolPool, functionPool, macroPool);
						if(JLispType.ERROR == tempValue.type) {
							popValueForDo(localVarList);//从let宏返回一定要记得将局部变量出栈
							return tempValue;
						}
						returnValue = tempValue;
					}
					popValueForDo(localVarList);//从let宏返回一定要记得将局部变量出栈
					return returnValue;
					
				}else {//等于2的情况，直接返回原子nil，记得出栈
					popValueForDo(localVarList);//从let宏返回一定要记得将局部变量出栈
					return new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
				}
			}else if(JLispMacroName.QUOTE == macro.macroName) {
				/*
				 * quote宏只能接受一个参数
				 */
				if(getLength() != 2) {
					return new JLispData(new Error("The macro \"quote\" expected 1 args"), JLispType.ERROR);
				}
				JLispData metaArg = getItemById(1);
				if(JLispType.ATOM == metaArg.type) {
					Atom atom = (Atom)(metaArg.data);
					if(null != atom.isClosureAtom) {//证明是闭包原子
						return new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM);
					}else {
						return metaArg;
					}
				}else if(JLispType.CONS == metaArg.type) {
					Cons cons = (Cons)(metaArg.data);
					if(needReplaceAtom(cons, symbolPool)) {//如果需要替换cons中的原子则返回一个新的包装数据，（在判断的函数中已将cons替换）
						return new JLispData(cons, JLispType.CONS);
					}else {//如果不需要则直接返回参数
						return metaArg;
					}
				}else {
					return metaArg;
				}
			}else if(JLispMacroName.REVERSEQUOTE == macro.macroName) {
				/*
				 * reversequote宏只能接受一个参数
				 */
				//先全部解析完成再执行
				/*
				(defmacro ma () `(object:create));
				(ma)
				*/
				if(getLength() != 2) {
					return new JLispData(new Error("The macro \"reversequote\" expected 1 args"), JLispType.ERROR);
				}
//				if(JLispType.CONS == this.getItemById(1).type && JLispType.CONS == ((Cons)(this.getItemById(1).data)).val.type) {
//					System.out.println(((Cons)(((Cons)(this.getItemById(1).data)).val.data)).isFunExpr);
//					System.out.println(((Cons)(((Cons)(this.getItemById(1).data)).val.data)).self);
//					
//				}
				JLispData ans = this.meltMacroCons(symbolPool).eval(symbolPool, functionPool, macroPool);
				if(JLispType.ATOM == ans.type) {
					Atom atom = (Atom)(ans.data);
					if(null != atom.isClosureAtom) {//证明是闭包原子
						return new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM);
					}else {
						return ans;
					}
				}else if(JLispType.CONS == ans.type) {
					Cons cons = (Cons)(ans.data);
					if(needReplaceAtom(cons, symbolPool)) {//如果需要替换cons中的原子则返回一个新的包装数据，（在判断的函数中已将cons替换）
						return new JLispData(cons, JLispType.CONS);
					}else {//如果不需要则直接返回参数
						return ans;
					}
				}else {
					return ans;
				}
				//分四种情况
				//原子
				//普通列表
				//逗号宏
				//at逗号宏
				/*JLispData metaArg = getItemById(1);
				if(JLispType.ATOM == metaArg.type) {
					Atom atom = (Atom)(metaArg.data);
					if(null != atom.isClosureAtom) {//证明是闭包原子
						return new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM);
					}else {
						return metaArg;
					}
				}else if(JLispType.CONS == metaArg.type) {
					int isSpecialMacro = isSpecialMacro(metaArg);
					if(isSpecialMacro != 0) {
						if(isSpecialMacro == 1) {//逗号宏
							Cons commacro = (Cons)(metaArg.data);
							return commacro.getItemById(1).eval(symbolPool, functionPool, macroPool);
						}else {//逗号at宏
							
						}
						
					}else {//list or cons
						Cons cons = (Cons)(metaArg.data);
						boolean needListFunction = needListFunction(cons.getItemById(cons.getLength() - 1));
						//System.out.println(needListFunction);
						//if(needListFunction) {//如果要用List函数去拼凑
							//(list (reversequote ad))
							String remakeStr = "(list";
							for(int i = 0;i < cons.getLength();i++) {
								remakeStr += " (reversequote"+" "+Terminal.getStringFromData(cons.getItemById(i))+")";
							}
							remakeStr += ")";
							JLispData remakeExpr = Terminal.getDataFromString(remakeStr, symbolPool);
							return remakeExpr.eval(symbolPool, functionPool, macroPool);
						//}else {//用cons函数去拼凑
							//for(int i = )
							
						//}
					}
					
				}else {
					
					return metaArg;
				}*/
			}else if(JLispMacroName.COMMA == macro.macroName) {//如果执行到了逗号宏，则直接返回错误，因为逗号宏已经在反引号宏中处理完了，不可能真正执行到逗号宏
				return new JLispData(new Error("Comma is illegal outside of backquote"), JLispType.ERROR);
			}else if(JLispMacroName.COMMAT == macro.macroName) {
				return new JLispData(new Error("Commat is illegal outside of backquote"), JLispType.ERROR);
			}else {//自定义宏
				JLispData[] args = new JLispData[getLength() - 1];
				for(int i = 1;i < getLength();i++) {
					args[i - 1] = getItemById(i);
				}
				//System.out.println(((Atom)(((Cons)((Cons)args[0].data).another.data).val.data)).isClosureAtom);
				
				functionPool.into(args, functionOrMacro, this.val);
				JLispData macroExpand = macro.execute(args, symbolPool, functionPool, macroPool);
//				Terminal.print(macroExpand);
//				System.out.println(((Cons)(((Cons)(macroExpand.data)).val.data)).isFunExpr);
//				System.out.println(((Cons)(((Cons)(macroExpand.data)).val.data)).self);
				functionPool.outfrom(functionOrMacro, macroExpand, this.val);
				/**
				 * 此处有bug遗留，当参数args中包含闭包原子或含有闭包原子的列表时，在执行execute方法后会替换掉闭包原子为一般原子，这时会造成闭包的丢失
				 * bug复现:
				 * (let ((x 12)) (defun fun nil (into (add x 1))));(fun);
				 * 虽然定义fun函数时捕获了局部变量x作为闭包，但在执行fun函数时由于into宏会进行宏展开，当展开后原本已经是闭包的x原子又被恢复成一般原子，
				 * 所以执行fun函数不会实现对应的使局部变量x加一的需求
				 * 修复工作量巨大，暂不处理
				 */
				//(let ((x 12)) (defun fun nil (into (add x 1))));(fun)
				//System.out.println(((Atom)((Cons)((Cons)((Cons)(((Cons)macroExpand.data).another).data).val.data).another.data).val.data) == symbolPool.getSymbolByString("x"));
				JLispData returnValue = macroExpand.eval(symbolPool, functionPool, macroPool);
				if(JLispType.ATOM == returnValue.type) {
					Atom atom = (Atom)(returnValue.data);
					if(null != atom.isClosureAtom) {//证明是闭包原子
						returnValue = new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM);
					}
				}else if(JLispType.CONS == returnValue.type) {
					Cons cons = (Cons)(returnValue.data);
					if(needReplaceAtom(cons, symbolPool)) {//如果需要替换cons中的原子则返回一个新的包装数据，（在判断的函数中已将cons替换）
						returnValue = new JLispData(cons, JLispType.CONS);
					}
				}
				return returnValue;//最后返回结果
			}
		}else {//否则返回未知错误，因为一般不会将一个原子的函数值设置为除函数和宏类型之外的值，如果返回未知错误的话则代表错误地给原子的函数值赋了值
			return new JLispData(new Error("Unknown Error!"), JLispType.ERROR);
		}
		return new JLispData(symbolPool.getSymbolByString("nil"), JLispType.ATOM);
	}
	private boolean isParseList(JLispData data) {
		if(JLispType.CONS != data.type) {
			return false;
		}
		Cons cons = (Cons)(data.data);
		if(JLispType.ATOM != cons.getItemById(0).type) {
			return false;
		}
		Atom atom = (Atom)(cons.getItemById(0).data);
		if(null == atom.functionEval()) {
			return false;
		}
		JLispData funOrMac = atom.functionEval();
		if(JLispType.FUNCTION != funOrMac.type) {
			return false;
		}
		Function function = (Function)(funOrMac.data);
		if(JLispFunctionName.PARSELIST != function.functionName) {
			return false;
		}
		return true;
	}
	/*private JLispData parseCons(SymbolPool symbolPool) {//解析自己这个列表
		if(getLength() != 2) {
			return new JLispData(new Error("The macro \"reversequote\" expected 2 args"), JLispType.ERROR);
		}
		//分四种情况
		//原子
		//普通列表
		//逗号宏
		//at逗号宏
		JLispData metaArg = getItemById(1);
		if(JLispType.ATOM == metaArg.type) {
			Atom atom = (Atom)(metaArg.data);
			if(null != atom.isClosureAtom) {//证明是闭包原子
				return new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM);
			}else {
				return metaArg;
			}
		}else if(JLispType.CONS == metaArg.type) {
			int isSpecialMacro = isSpecialMacro(metaArg);
			if(isSpecialMacro != 0) {
				if(isSpecialMacro == 1) {//逗号宏
					Cons commacro = (Cons)(metaArg.data);
					return commacro.getItemById(1).eval(symbolPool, functionPool, macroPool);
				}else {//逗号at宏
					
				}
				
			}else {//list or cons
				Cons cons = (Cons)(metaArg.data);
				boolean needListFunction = needListFunction(cons.getItemById(cons.getLength() - 1));
				if(needListFunction) {//如果要用List函数去拼凑
					//(list (reversequote ad))
					String remakeStr = "(list";
					for(int i = 0;i < cons.getLength();i++) {
						remakeStr += " (reversequote"+" "+Terminal.getStringFromData(cons.getItemById(i))+")";
					}
					remakeStr += ")";
					JLispData remakeExpr = Terminal.getDataFromString(remakeStr, symbolPool);
					return remakeExpr.eval(symbolPool, functionPool, macroPool);
				}else {//用cons函数去拼凑
					//for(int i = )
					
				}
			}
			
		}else {
			
			return metaArg;
		}
	}*/
	public JLispData meltMacroCons(SymbolPool symbolPool) {//只有反引号列表才进行转换
		if(this.getLength() != 2) {//反引号宏列表长度只能是2
			return new JLispData(new Error("Reversequote macro expected 1 args, but found "+this.getLength()+" args"), JLispType.ERROR);
		}
		if(!this.isReverseQuote()) {//如果该列表不是反引号列表，则直接返回
			return new JLispData(new Error("Melt Macro can only happens to reversequote macro"), JLispType.ERROR);
		}
		JLispData metaArg = this.getItemById(1);
		if(JLispType.ATOM == metaArg.type) {
			this.setItemById(0, new JLispData(symbolPool.getSymbolByString("quote"), JLispType.ATOM));
			return new JLispData(this, JLispType.CONS);
		}else if(JLispType.CONS == metaArg.type) {
			Cons cons = (Cons)(metaArg.data);
			if(cons.isReverseQuote()) {//如果是反引号宏列表
				/*cons = (Cons)(cons.meltMacroCons(symbolPool).data);//转换列表
				JLispData[] listItem = new JLispData[cons.getLength() + 1];
				listItem[0] = new JLispData(symbolPool.getSymbolByString("list"), JLispType.ATOM);
				for(int i = 1;i < listItem.length;i++) {
					listItem[i] = addReverseQuoteAndMelt(this.getItemById(0), cons.getItemById(i - 1), symbolPool);
				}
				return new JLispData(new Cons(listItem, symbolPool.getSymbolByString("nil")), JLispType.CONS);*/
				
				this.setItemById(1, cons.meltMacroCons(symbolPool));
				return this.meltMacroCons(symbolPool);
			}else if(isSpecialMacro(new JLispData(cons, JLispType.CONS)) == 1) {//是逗号宏列表
				JLispData data = cons.getItemById(1);
				if(JLispType.CONS != data.type) {
					return data;
				}else {
					Cons revOrComOrCustom = (Cons)(data.data);
					if(revOrComOrCustom.isReverseQuote()) {//如果又是反引号宏列表，则返回这个宏列表的解析列表
						return revOrComOrCustom.meltMacroCons(symbolPool);
					}else if(isSpecialMacro(data) == 1){//如果又是逗号宏列表，则直接返回这个逗号宏列表
						return data;
					}else {
						//如果去掉此段代码的注释则代表`,(`,a)会被解析成(a)，不去掉则代表被解析成(`,a)，一般使用后者
						/*for(int i = 0;i < revOrComOrCustom.getLength();i++) {
							JLispData item = revOrComOrCustom.getItemById(i);
							if(JLispType.CONS == item.type && ((Cons)(item.data)).isReverseQuote()) {
								revOrComOrCustom.setItemById(i, ((Cons)(item.data)).meltMacroCons(symbolPool));
							}
						}*/
						return data;
					}
				}
			}else if(isSpecialMacro(new JLispData(cons, JLispType.CONS)) == 2) {//是逗号宏at列表
				JLispData data = cons.getItemById(1);
				if(JLispType.CONS != data.type) {
					//return data;
					return new JLispData(new Cons(new JLispData[]{new JLispData(symbolPool.getSymbolByString("parselist"), JLispType.ATOM), data},
							symbolPool.getSymbolByString("nil")), JLispType.CONS);
				}else {
					Cons revOrComOrCustom = (Cons)(data.data);
					if(revOrComOrCustom.isReverseQuote()) {//如果又是反引号宏列表，则返回这个宏列表的解析列表
						//return revOrComOrCustom.meltMacroCons(symbolPool);
						return new JLispData(new Cons(new JLispData[]{new JLispData(symbolPool.getSymbolByString("parselist"), JLispType.ATOM), revOrComOrCustom.meltMacroCons(symbolPool)},
								symbolPool.getSymbolByString("nil")), JLispType.CONS);
					}else if(isSpecialMacro(data) == 1 || isSpecialMacro(data) == 2){//如果又是逗号宏列表，则直接返回这个逗号宏列表
						return new JLispData(new Cons(new JLispData[]{new JLispData(symbolPool.getSymbolByString("parselist"), JLispType.ATOM), data},
								symbolPool.getSymbolByString("nil")), JLispType.CONS);
					}else {
						//如果去掉此段代码的注释则代表`,(`,a)会被解析成(a)，不去掉则代表被解析成(`,a)，一般使用后者
						/*for(int i = 0;i < revOrComOrCustom.getLength();i++) {
							JLispData item = revOrComOrCustom.getItemById(i);
							if(JLispType.CONS == item.type && ((Cons)(item.data)).isReverseQuote()) {
								revOrComOrCustom.setItemById(i, ((Cons)(item.data)).meltMacroCons(symbolPool));
							}
						}*/
						return new JLispData(new Cons(new JLispData[]{new JLispData(symbolPool.getSymbolByString("parselist"), JLispType.ATOM), data},
								symbolPool.getSymbolByString("nil")), JLispType.CONS);
					}
				}
				
			}else {//普通列表
				JLispData[] listItem = new JLispData[cons.getLength() + 1];
				listItem[0] = new JLispData(symbolPool.getSymbolByString("list"), JLispType.ATOM);
				for(int i = 1;i < listItem.length;i++) {
					listItem[i] = addReverseQuoteAndMelt(this.getItemById(0), cons.getItemById(i - 1), symbolPool);
				}
				return new JLispData(getEasyCons(new Cons(listItem, symbolPool.getSymbolByString("nil")), symbolPool), JLispType.CONS);
			}
		}else {
			return new JLispData(this, JLispType.CONS);
		}
	}
	private Cons getEasyCons(Cons cons, SymbolPool symbolPool) {//化简列表的函数，如(list (quote a) (quote b)) 可以化简为(quote (a b))
		if(JLispType.ATOM != cons.getItemById(0).type) {
			return cons;
		}
		Atom atom = (Atom)(cons.getItemById(0).data);
		if(!"list".equalsIgnoreCase(atom.name)) {
			return cons;
		}
		if(cons.getLength() == 1) {
			return cons;
		}
		JLispData[] consDatas = new JLispData[cons.getLength() - 1];
		for(int i = 1;i < cons.getLength();i++) {
			if(JLispType.CONS != cons.getItemById(i).type) {
				return cons;
			}
			Cons itemCons = (Cons)(cons.getItemById(i).data);
			if(itemCons.getLength() != 2) {
				return cons;
			}
			if(JLispType.ATOM != itemCons.getItemById(0).type) {
				return cons;
			}
			Atom isQuote = (Atom)(itemCons.getItemById(0).data);
			if(!"quote".equalsIgnoreCase(isQuote.name)) {
				return cons;
			}
			consDatas[i - 1] = itemCons.getItemById(1);
		}
		return new Cons(new JLispData[]{new JLispData(symbolPool.getSymbolByString("quote"), JLispType.ATOM),
				new JLispData(new Cons(consDatas, symbolPool.getSymbolByString("nil")), JLispType.CONS)},
				symbolPool.getSymbolByString("nil"));
	}
	private JLispData addReverseQuoteAndMelt(JLispData reverseQuote, JLispData data, SymbolPool symbolPool) {
		
		return new Cons(new JLispData[]{reverseQuote, data}, symbolPool.getSymbolByString("nil")).meltMacroCons(symbolPool);
	}
	/*暂时不考虑用Cons函数解析列表，所以这个方法暂时不用
	private boolean needListFunction(JLispData data) {
		if(JLispType.CONS == data.type) {
			
			if(isSpecialMacro(data) != 0) {
				return true;
			}
			Cons cons = (Cons)(data.data);
			for(int i = 0;i < cons.getLength();i++) {
				if(needListFunction(cons.getItemById(i))) {
					return true;
				}
			}
			return false;
		}
		return false;
	}*/
	private int isSpecialMacro(JLispData data) {//能与反引号匹配的如：,a  ,(fun a b c) ,@a
		if(JLispType.CONS != data.type) {//不是列表
			return 0;
		}
		Cons cons = (Cons)(data.data);
		JLispData isCommaOrCommat = cons.getItemById(0);
		if(JLispType.ATOM == isCommaOrCommat.type) {//如果第一个元素是原子且是逗号或逗号at宏
			Atom corcat = (Atom)(isCommaOrCommat.data);
			if(null != corcat.functionEval()) {
				if(JLispType.MACRO == corcat.functionEval().type) {
					Macro coca = (Macro)(corcat.functionEval().data);
					if(JLispMacroName.COMMA == coca.macroName) {
						return 1;
					}else if(JLispMacroName.COMMAT == coca.macroName) {
						return 2;
					}else {//list或cons（不为特殊宏的原子）
						return 0;
					}
				}else {//list或cons（函数值不为宏的原子）
					return 0;
				}
			}else {//list或cons（没有函数值的原子）
				return 0;
			}
		}else {//list或cons(不是原子)
			return 0;
		}
	}
	private boolean isReverseQuote() {//判断cons是不是反引号宏列表
		JLispData isAtom = this.getItemById(0);
		if(JLispType.ATOM == isAtom.type) {//如果第一个元素是原子且是逗号或逗号at宏
			Atom isReverseQuote = (Atom)(isAtom.data);
			if(null != isReverseQuote.functionEval()) {
				if(JLispType.MACRO == isReverseQuote.functionEval().type) {
					Macro macro = (Macro)(isReverseQuote.functionEval().data);
					if(JLispMacroName.REVERSEQUOTE == macro.macroName) {
						return true;
					}else {
						return false;
					}
				}else {
					return false;
				}
			}else {
				return false;
			}
		}else {
			return false;
		}
	}
	private boolean needReplaceAtom(Cons cons, SymbolPool symbolPool) {//判断一个列表中是否有闭包原子，如果有则替换成符号池中的原子并返回真，没有则不做操作返回假
		boolean needReplace = false;
		for(int i = 0;i < cons.getLength();i++) {
			JLispData item = cons.getItemById(i);
			if(JLispType.ATOM == item.type) {
				Atom atom = (Atom)(item.data);
				if(null != atom.isClosureAtom) {//证明是闭包原子
					cons.setItemById(i, new JLispData(symbolPool.getSymbolByString(atom.name), JLispType.ATOM));
					needReplace = true;
				}
			}else if(JLispType.CONS == item.type) {
				Cons consOfCons = (Cons)(item.data);
				if(!needReplace) {//只有当为假的情况才需要受下一次递归的控制
					needReplace = needReplaceAtom(consOfCons, symbolPool);
				}else {//如果已经为真了，则不需要受下一次递归的控制了
					needReplaceAtom(consOfCons, symbolPool);
				}
			}
		}
		return needReplace;
	}
	private void pushValueForDo(Atom var, JLispData value) {//供do宏使用的局部变量初始化方法
		var.setValue(value);
	}
	private void popValueForDo(List<Cons> localVarList) {
		for(Cons argList:localVarList) {
			((Atom)(argList.getItemById(0).data)).pop();
		}
	}
	private void resetValueForDo(Atom var, JLispData value) {
		
		var.resetValue(value);
	}
	private List<Atom> getClosure(JLispData argOrNil, List<JLispData> functionBodys, SymbolPool symbolPool, JLispData functionOrMacro) {//遍历所有的函数体中的原子
		Function function = null;
		Macro macro = null;
		if(JLispType.FUNCTION == functionOrMacro.type) {
			function = (Function)(functionOrMacro.data);
		}else if(JLispType.MACRO == functionOrMacro.type) {
			macro = (Macro)(functionOrMacro.data);
		}
		//绑定闭包
		/*
		 * 如果是一个列表，则绑定不为
		 */
		List<Atom> closure = new ArrayList<Atom>();//最终将要返回的闭包集合
		
		List<Atom> notBindAtoms = new ArrayList<Atom>();//不绑定原子集合，例如参数中的原子以及一些定义局部变量的首个原子就是不需要绑定的
		if(argOrNil.type == JLispType.CONS) {//如果参数列表为列表，则将参数列表中的原子添加进不绑定原子集合中
			for(int i = 0;i < ((Cons)(argOrNil.data)).getLength();i++) {
				JLispData arg = ((Cons)(argOrNil.data)).getItemById(i);
				if(arg.type == JLispType.ATOM) {
					if("&rest".equalsIgnoreCase(((Atom)(arg.data)).name)) {
						continue;
					}
					notBindAtoms.add((Atom)(arg.data));
				}
			}
		}
		for(int i = 0;i < functionBodys.size();i++) {
			if(functionBodys.get(i).type == JLispType.ATOM) {
				Atom a = (Atom)(functionBodys.get(i).data);
				if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
					//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
					boolean have = false;
					for(int j = 0;j < closure.size();j++) {
						if(a == closure.get(j)) {
							have = true;
							break;
						}
					}
					if(!have) {
						closure.add(a);
					}
					continue;
				}
				a = symbolPool.getSymbolByString(a.name);//这时候a有可能是闭包的情况（a为闭包且当前符号池中a原子也有值），不管怎么样到这步都必须赋值为正常原子，确保不再是闭包原子
				if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
					boolean needBind = true;
					for(Atom notBindAtom:notBindAtoms) {
						if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
							needBind = false;
							break;
						}
					}
					if(needBind) {//如果需要绑定该原子
						//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
						Atom coa = null;
						for(Atom clo:closure) {
							if(clo.name.equalsIgnoreCase(a.name)) {
								coa = clo;
								break;
							}
						}
						if(null == coa) {//如果还没有绑定，则执行绑定操作
							coa = new Atom(a.name);
							if(null != function) {
								coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
							}else if(null != macro) {
								coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
							}
							closure.add(coa);
						}
						//替换操作
						functionBodys.set(i, new JLispData(coa, JLispType.ATOM));
					}
				}
			}else if(functionBodys.get(i).type == JLispType.CONS) {
				Cons cons = (Cons)(functionBodys.get(i).data);
				if(null != function) {
					testArg(closure, notBindAtoms, cons, symbolPool, new JLispData(function, JLispType.FUNCTION));
				}else if(null != macro) {
					testArg(closure, notBindAtoms, cons, symbolPool, new JLispData(macro, JLispType.MACRO));
				}
				
			}
		}
		return closure;
	}
	private void testArg(List<Atom> closure, List<Atom> notBindAtoms, Cons cons, SymbolPool symbolPool, JLispData functionOrMacro) {
		Function function = null;
		Macro macro = null;
		if(JLispType.FUNCTION == functionOrMacro.type) {
			function = (Function)(functionOrMacro.data);
		}else if(JLispType.MACRO == functionOrMacro.type) {
			macro = (Macro)(functionOrMacro.data);
		}
		/*
		 * 如果第一个是原子
		 */
		if(cons.getItemById(0).type == JLispType.ATOM) {
			Atom first = (Atom)(cons.getItemById(0).data);
			if((!cons.isLetArgs) && (!cons.isDoArgs) && (null == first.symbolValues)) {//如果第一个原子的值栈为空，代表这是一个特殊原子，此时对这个列表中的其它原子不做处理
				new Error("The special atom \""+first.name+"\" is not a function or macro, can not infer the next atom's value"
						+ " from the atom or the closure");
				for(int i = 1;i < cons.getLength();i++) {
					if(cons.getItemById(i).type == JLispType.CONS) {
						if(null != function) {
							testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
						}else if(null != macro) {
							testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
						}
					}
				}
				
			}else if((!cons.isLetArgs) && (!cons.isDoArgs) && (first.functionEval() != null) && (first.functionEval().type == JLispType.MACRO)){//如果函数值为宏，则只处理一些特殊的宏
				Macro _macro = (Macro)(first.functionEval().data);
				if(JLispMacroName.LET == _macro.macroName) {
					/*
					 * (let ((a 12)) (+ 1 2))
					 */
					if(cons.getLength() < 2) {
						new Error("The macro \"let\" needs at least 1 args");
					}else {
						int notBindsLengthBefore = notBindAtoms.size();
						if(JLispType.ATOM == cons.getItemById(1).type) {
							Atom nil = (Atom)(cons.getItemById(1).data);
							if(!"nil".equalsIgnoreCase(nil.name)) {
								new Error("The macro let needs a list(\"nil\" or \"((var value) ...)\") to declare local variables");
							}
							
						}else if(JLispType.CONS == cons.getItemById(1).type) {
							Cons list = (Cons)(cons.getItemById(1).data);
							
							for(int i = 0;i < list.getLength();i++) {
								if(JLispType.CONS == list.getItemById(i).type) {
									Cons varList = (Cons)(list.getItemById(i).data);
									varList.isLetArgs = true;
									if(null != function) {
										testArg(closure, notBindAtoms, varList, symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, varList, symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}else {
									new Error("The variable list should not have the data except the cons");
								}
							}
						}else {
							new Error("The macro let needs a list(\"nil\" or \"((var value) ...)\") to declare local variables");
						}
						int notBindsLengthAfter = notBindAtoms.size();
						for(int i = 2;i < cons.getLength();i++) {
							if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
								Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
								if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
									//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
									boolean have = false;//闭包中是否已经有这个原子
									for(int j = 0;j < closure.size();j++) {
										if(a == closure.get(j)) {
											have = true;
											break;
										}
									}
									if(!have) {
										closure.add(a);
									}
									continue;
								}
								a = symbolPool.getSymbolByString(a.name);
								if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
									boolean needBind = true;
									for(Atom notBindAtom:notBindAtoms) {
										if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
											needBind = false;
											break;
										}
									}
									if(needBind) {//如果需要绑定该原子
										//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
										Atom coa = null;
										for(Atom clo:closure) {
											if(clo.name.equalsIgnoreCase(a.name)) {
												coa = clo;
												break;
											}
										}
										if(null == coa) {//如果还没有绑定，则执行绑定操作
											coa = new Atom(a.name);
											if(null != function) {
												coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
											}else if(null != macro) {
												coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
											}
											
											closure.add(coa);
										}
										//替换操作(将列表的该原子替换成闭包原子)
										cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
										
									}
								}
							}else if(JLispType.CONS == cons.getItemById(i).type) {
								if(null != function) {
									testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
								}else if(null != macro) {
									testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
								}
							}
						}
						for(int index = notBindsLengthAfter - 1;index > notBindsLengthBefore - 1;index--) {
							notBindAtoms.remove(index);
						}
					}
				}else if(JLispMacroName.DO == _macro.macroName) {
					if(cons.getLength() < 3) {
						new Error("The macro \"do\" needs at least 2 args");
					}else {
						int notBindsLengthBefore = notBindAtoms.size();//获取当前不绑定原子集合的大小
						if(JLispType.ATOM == cons.getItemById(1).type) {//如果变量声明列表是原子的话则必须是nil原子，否则产生警告
							Atom nil = (Atom)(cons.getItemById(1).data);
							if(!"nil".equalsIgnoreCase(nil.name)) {
								new Error("The macro \"do\" needs a list(\"nil\" or \"((var value increase) ...)\") to declare local variables");
							}
							
						}else if(JLispType.CONS == cons.getItemById(1).type) {
							Cons list = (Cons)(cons.getItemById(1).data);
							for(int i = 0;i < list.getLength();i++) {
								if(JLispType.CONS == list.getItemById(i).type) {
									Cons varList = (Cons)(list.getItemById(i).data);
									varList.isDoArgs = true;
									if(null != function) {
										testArg(closure, notBindAtoms, varList, symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, varList, symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}else {
									new Error("The variable list should not have the data except the cons");
								}
							}
							for(int i = 0;i < list.getLength();i++) {
								if(JLispType.CONS == list.getItemById(i).type) {
									Cons varList = (Cons)(list.getItemById(i).data);
									for(int j = 2;j < varList.getLength();j++) {
										if(JLispType.ATOM == varList.getItemById(j).type) {//如果是原子，则看要不要绑定
											Atom a = (Atom)(varList.getItemById(j).data);//获取这个原子
											if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
												//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
												boolean have = false;//闭包中是否已经有这个原子
												for(int m = 0;m < closure.size();m++) {
													if(a == closure.get(m)) {
														have = true;
														break;
													}
												}
												if(!have) {
													closure.add(a);
												}
												continue;
											}
											a = symbolPool.getSymbolByString(a.name);
											if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
												boolean needBind = true;
												for(Atom notBindAtom:notBindAtoms) {
													if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
														needBind = false;
														break;
													}
												}
												if(needBind) {//如果需要绑定该原子
													//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
													Atom coa = null;
													for(Atom clo:closure) {
														if(clo.name.equalsIgnoreCase(a.name)) {
															coa = clo;
															break;
														}
													}
													if(null == coa) {//如果还没有绑定，则执行绑定操作
														coa = new Atom(a.name);
														if(null != function) {
															coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
														}else if(null != macro) {
															coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
														}
														closure.add(coa);
													}
													//替换操作(将列表的该原子替换成闭包原子)
													varList.setItemById(j, new JLispData(coa, JLispType.ATOM));
													
												}
											}
										}else if(JLispType.CONS == varList.getItemById(j).type) {
											if(null != function) {
												//test
												testArg(closure, notBindAtoms, ((Cons)(varList.getItemById(j).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
											}else if(null != macro) {
												//test
												testArg(closure, notBindAtoms, ((Cons)(varList.getItemById(j).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
											}
										}
									}
								}
							}
						}else {
							new Error("The macro do needs a list(\"nil\" or \"((var value increase) ...)\") to declare local variables");
						}
						int notBindsLengthAfter = notBindAtoms.size();
						if(JLispType.ATOM == cons.getItemById(2).type) {
							new Error("The macro do needs a list to be exit clause");
						}else if(JLispType.CONS == cons.getItemById(2).type) {
							Cons clause = (Cons)(cons.getItemById(2).data);
							for(int i = 0;i < clause.getLength();i++) {
								if(JLispType.ATOM == clause.getItemById(i).type) {//如果是原子，则看要不要绑定
									Atom a = (Atom)(clause.getItemById(i).data);//获取这个原子
									if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
										//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
										boolean have = false;//闭包中是否已经有这个原子
										for(int j = 0;j < closure.size();j++) {
											if(a == closure.get(j)) {
												have = true;
												break;
											}
										}
										if(!have) {
											closure.add(a);
										}
										continue;
									}
									a = symbolPool.getSymbolByString(a.name);
									if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
										boolean needBind = true;
										for(Atom notBindAtom:notBindAtoms) {
											if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
												needBind = false;
												break;
											}
										}
										if(needBind) {//如果需要绑定该原子
											//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
											Atom coa = null;
											for(Atom clo:closure) {
												if(clo.name.equalsIgnoreCase(a.name)) {
													coa = clo;
													break;
												}
											}
											if(null == coa) {//如果还没有绑定，则执行绑定操作
												coa = new Atom(a.name);
												if(null != function) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
												}else if(null != macro) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
												}
												closure.add(coa);
											}
											//替换操作(将列表的该原子替换成闭包原子)
											clause.setItemById(i, new JLispData(coa, JLispType.ATOM));
											
										}
									}
								}else if(JLispType.CONS == cons.getItemById(i).type) {
									if(null != function) {
										testArg(closure, notBindAtoms, ((Cons)(clause.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, ((Cons)(clause.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}
							}
						}else {
							new Error("The macro do needs a list to be exit clause");
						}
						if(cons.getLength() > 3) {
							for(int i = 3;i < cons.getLength();i++) {
								if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
									Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
									if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
										//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
										boolean have = false;//闭包中是否已经有这个原子
										for(int j = 0;j < closure.size();j++) {
											if(a == closure.get(j)) {
												have = true;
												break;
											}
										}
										if(!have) {
											closure.add(a);
										}
										continue;
									}
									a = symbolPool.getSymbolByString(a.name);
									if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
										boolean needBind = true;
										for(Atom notBindAtom:notBindAtoms) {
											if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
												needBind = false;
												break;
											}
										}
										if(needBind) {//如果需要绑定该原子
											//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
											Atom coa = null;
											for(Atom clo:closure) {
												if(clo.name.equalsIgnoreCase(a.name)) {
													coa = clo;
													break;
												}
											}
											if(null == coa) {//如果还没有绑定，则执行绑定操作
												coa = new Atom(a.name);
												if(null != function) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
												}else if(null != macro) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
												}
												closure.add(coa);
											}
											//替换操作(将列表的该原子替换成闭包原子)
											cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
											
										}
									}
								}else if(JLispType.CONS == cons.getItemById(i).type) {
									if(null != function) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}
							}
						}
						for(int index = notBindsLengthAfter - 1;index > notBindsLengthBefore - 1;index--) {
							notBindAtoms.remove(index);
						}
					}
				}else if(JLispMacroName.DEFUN == _macro.macroName) {
					if(cons.getLength() < 3) {
						new Error("The macro \"defun\" needs at least 3 args");
					}else {
						int notBindsLengthBefore = notBindAtoms.size();
						if(JLispType.ATOM != cons.getItemById(1).type) {
							new Error("The macro \"defun\" needs an atom as the function name");
						}
						if(JLispType.ATOM == cons.getItemById(2).type) {
							Atom name = (Atom)(cons.getItemById(2).data);
							if(!"nil".equalsIgnoreCase(name.name)) {
								new Error("The macro \"defun\" needs a list(\"nil\" or \"(arg0 ...)\") to be an args");
							}
						}else if(JLispType.CONS == cons.getItemById(2).type) {
							Cons args = (Cons)(cons.getItemById(2).data);
							for(int i = 0;i < args.getLength();i++) {
								JLispData arg = args.getItemById(i);
								if(arg.type == JLispType.ATOM) {
									if("&rest".equalsIgnoreCase(((Atom)(arg.data)).name)) {
										continue;
									}
									notBindAtoms.add((Atom)(arg.data));
								}
							}
						}else {
							new Error("The macro \"defun\" needs a list(\"nil\" or \"(arg0 ...)\") to be an args");
						}
						int notBindsLengthAfter = notBindAtoms.size();
						if(cons.getLength() > 3) {
							for(int i = 3;i < cons.getLength();i++) {
								if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
									Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
									if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
										//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
										boolean have = false;//闭包中是否已经有这个原子
										for(int j = 0;j < closure.size();j++) {
											if(a == closure.get(j)) {
												have = true;
												break;
											}
										}
										if(!have) {
											closure.add(a);
										}
										continue;
									}
									a = symbolPool.getSymbolByString(a.name);
									if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
										boolean needBind = true;
										for(Atom notBindAtom:notBindAtoms) {
											if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
												needBind = false;
												break;
											}
										}
										if(needBind) {//如果需要绑定该原子
											//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
											Atom coa = null;
											for(Atom clo:closure) {
												if(clo.name.equalsIgnoreCase(a.name)) {
													coa = clo;
													break;
												}
											}
											if(null == coa) {//如果还没有绑定，则执行绑定操作
												coa = new Atom(a.name);
												if(null != function) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
												}else if(null != macro) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
												}
												closure.add(coa);
											}
											//替换操作(将列表的该原子替换成闭包原子)
											cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
										}
									}
								}else if(JLispType.CONS == cons.getItemById(i).type) {
									if(null != function) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}
							}
						}
						for(int index = notBindsLengthAfter - 1;index > notBindsLengthBefore - 1;index--) {
							notBindAtoms.remove(index);
						}
					}
				}else if(JLispMacroName.DEFMACRO == _macro.macroName) {
					if(cons.getLength() < 3) {
						new Error("The macro \"defmacro\" needs at least 3 args");
					}else {
						int notBindsLengthBefore = notBindAtoms.size();
						if(JLispType.ATOM != cons.getItemById(1).type) {
							new Error("The macro \"defmacro\" needs an atom as the function name");
						}
						if(JLispType.ATOM == cons.getItemById(2).type) {
							Atom name = (Atom)(cons.getItemById(2).data);
							if(!"nil".equalsIgnoreCase(name.name)) {
								new Error("The macro \"defmacro\" needs a list(\"nil\" or \"(arg0 ...)\") to be an args");
							}
						}else if(JLispType.CONS == cons.getItemById(2).type) {
							Cons args = (Cons)(cons.getItemById(2).data);
							for(int i = 0;i < args.getLength();i++) {
								JLispData arg = args.getItemById(i);
								if(arg.type == JLispType.ATOM) {
									if("&rest".equalsIgnoreCase(((Atom)(arg.data)).name)) {
										continue;
									}
									notBindAtoms.add((Atom)(arg.data));
								}
							}
						}else {
							new Error("The macro \"defmacro\" needs a list(\"nil\" or \"(arg0 ...)\") to be an args");
						}
						int notBindsLengthAfter = notBindAtoms.size();
						if(cons.getLength() > 3) {
							for(int i = 3;i < cons.getLength();i++) {
								if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
									Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
									if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
										//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
										boolean have = false;//闭包中是否已经有这个原子
										for(int j = 0;j < closure.size();j++) {
											if(a == closure.get(j)) {
												have = true;
												break;
											}
										}
										if(!have) {
											closure.add(a);
										}
										continue;
									}
									a = symbolPool.getSymbolByString(a.name);
									if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
										boolean needBind = true;
										for(Atom notBindAtom:notBindAtoms) {
											if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
												needBind = false;
												break;
											}
										}
										if(needBind) {//如果需要绑定该原子
											//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
											Atom coa = null;
											for(Atom clo:closure) {
												if(clo.name.equalsIgnoreCase(a.name)) {
													coa = clo;
													break;
												}
											}
											if(null == coa) {//如果还没有绑定，则执行绑定操作
												coa = new Atom(a.name);
												if(null != function) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
												}else if(null != macro) {
													coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
												}
												closure.add(coa);
											}
											//替换操作(将列表的该原子替换成闭包原子)
											cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
										}
									}
								}else if(JLispType.CONS == cons.getItemById(i).type) {
									if(null != function) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
									}
								}
							}
						}
						for(int index = notBindsLengthAfter - 1;index > notBindsLengthBefore - 1;index--) {
							notBindAtoms.remove(index);
						}
					}
				}else {
					//如果是其它宏，则像其它情况一样处理就行
					for(int i = 1;i < cons.getLength();i++) {
						if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
							Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
							if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
								//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
								boolean have = false;//闭包中是否已经有这个原子
								for(int j = 0;j < closure.size();j++) {
									if(a == closure.get(j)) {
										have = true;
										break;
									}
								}
								if(!have) {
									closure.add(a);
								}
								continue;
							}
							a = symbolPool.getSymbolByString(a.name);
							if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
								boolean needBind = true;
								for(Atom notBindAtom:notBindAtoms) {
									if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
										needBind = false;
										break;
									}
								}
								if(needBind) {//如果需要绑定该原子
									//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
									Atom coa = null;
									for(Atom clo:closure) {
										if(clo.name.equalsIgnoreCase(a.name)) {
											coa = clo;
											break;
										}
									}
									if(null == coa) {//如果还没有绑定，则执行绑定操作
										coa = new Atom(a.name);
										if(null != function) {
											coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
										}else if(null != macro) {
											coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
										}
										closure.add(coa);
									}
									//替换操作(将列表的该原子替换成闭包原子)
									cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
									
								}
							}
						}else if(JLispType.CONS == cons.getItemById(i).type) {
							if(null != function) {
								testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
							}else if(null != macro) {
								testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
							}
						}
					}
				}
			}else {//如果是函数，或者没有函数值的情况，
				for(int i = 1;i < cons.getLength();i++) {
					if(i > 1) {
						if(cons.isDoArgs) {//如果列表是do宏里的参数列表，则只对索引值为1的参数进行绑定，然后将索引值为0的原子添加进不绑定原子集合，剩下的参数由上面的
							//do宏分支进行统一处理
							break;
						}
					}
					if(JLispType.ATOM == cons.getItemById(i).type) {//如果是原子，则看要不要绑定
						Atom a = (Atom)(cons.getItemById(i).data);//获取这个原子
						if(null != a.isClosureAtom && null == symbolPool.getSymbolByString(a.name).symbolValues.now()) {//如果a原子已经是一个闭包原子并且当前符号池中的该符号没有值的情况则直接进入下一轮循环
							//表示继续复用这个旧的已经被绑定过的闭包（这种情况很特殊，发生在在函数中定义函数的情境下）
							boolean have = false;//闭包中是否已经有这个原子
							for(int j = 0;j < closure.size();j++) {
								if(a == closure.get(j)) {
									have = true;
									break;
								}
							}
							if(!have) {
								closure.add(a);
							}
							continue;
						}
						a = symbolPool.getSymbolByString(a.name);
						if(null != a.symbolValues) {//如果a的值栈不为空，也就是a不是特殊原子
							boolean needBind = true;
							for(Atom notBindAtom:notBindAtoms) {
								if(notBindAtom == a) {//如果该原子在不绑定原子集合中，则不需要绑定该原子
									needBind = false;
									break;
								}
							}
							if(needBind) {//如果需要绑定该原子
								//检查闭包中是否已经有了该原子，如果没有，则执行绑定操作
								Atom coa = null;
								for(Atom clo:closure) {
									if(clo.name.equalsIgnoreCase(a.name)) {
										coa = clo;
										break;
									}
								}
								if(null == coa) {//如果还没有绑定，则执行绑定操作
									coa = new Atom(a.name);
									if(null != function) {
										coa.isClosureAtom = a.symbolValues.bind(new JLispData(function, JLispType.FUNCTION));
									}else if(null != macro) {
										coa.isClosureAtom = a.symbolValues.bind(new JLispData(macro, JLispType.MACRO));
									}
									closure.add(coa);
								}
								//替换操作(将列表的该原子替换成闭包原子)
								cons.setItemById(i, new JLispData(coa, JLispType.ATOM));
								
							}
						}
					}else if(JLispType.CONS == cons.getItemById(i).type) {
						if(null != function) {
							testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
						}else if(null != macro) {
							testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
						}
					}
				}
				if(cons.isLetArgs || cons.isDoArgs) {
					if(JLispType.ATOM != cons.getItemById(0).type) {
						new Error("The local variable should be an atom");
					}else {
						notBindAtoms.add((Atom)(cons.getItemById(0).data));
					}
				}
			}
		}else {//如果第一个元素不是原子
			/*
			 * ((+ a b) (- c d))
			 */
			new Error("The first cons item is not a symbol, can not infer the next atom's value"
					+ " from the atom or the closure");
			for(int i = 0;i < cons.getLength();i++) {
				if(cons.getItemById(i).type == JLispType.CONS) {
					if(null != function) {
						testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(function, JLispType.FUNCTION));
					}else if(null != macro) {
						testArg(closure, notBindAtoms, ((Cons)(cons.getItemById(i).data)), symbolPool, new JLispData(macro, JLispType.MACRO));
					}
				}
			}
			
		}
		
	}

	private boolean canBeArgs(Cons args, Atom rest) {//判断一个列表能不能作为一个函数或者宏的参数列表
		/*
		 * 首先判断是否全部为正确的原子（特殊原子是不被允许的）
		 */
		for(int i = 0;i < args.getLength();i++) {
			//((Atom)(args.getItemById(i).data))
			if(args.getItemById(i).type != JLispType.ATOM || 
					((Atom)(args.getItemById(i).data)).symbolValues == null) {
				if(JLispType.ATOM != args.getItemById(i).type) {
					return false;
				}
				if("&rest".equalsIgnoreCase(((Atom)(args.getItemById(i).data)).name)) {//&rest原子除外，它可以作为参数
					continue;
				}
				return false;
			}
		}
		if(args.indexOfAtom(rest) == -1) {//如果参数列表中没有&rest原子则返回真
			return true;
		}else if(args.indexOfAtom(rest) != args.getLength() - 2){//如果有rest原子但是不在指定位置上则返回假
			return false;
		}
		return true;
		
	}
	
	
	/*
	 * 这个函数表示判断该列表是不是特殊列表
	 */
	public boolean isSpecialCons() {
		if(JLispType.ATOM == this.another.type) {//如果右值为原子的话，则只有在为nil原子的时候才不为点对列表，否则就是点对列表
			Atom a = (Atom)(this.another.data);
			if("nil".equalsIgnoreCase(a.name)) {
				return false;
			}else {
				return true;
			}
		}else if(JLispType.CONS == this.another.type) {//如果右值为Cons列表的话则递归
			return ((Cons)(this.another.data)).isSpecialCons();
		}else {//如果右值为其它类型的值则肯定为特殊列表
			return true;
		}
	}
	
	
	
	/*
	 * 这个函数表示获取该Cons值的长度
	 */
	private int getConsLength() {
		if(!(JLispType.CONS == this.another.type)) {//如果这个列表的右值不为Cons的话，则该Cons的长度为1，
			//（不是2，因为右值为nil的时候这个Cons才是一个列表，长度为1，或者右值为其它不是Cons类型的值的时候其长度同样为1，只不过是特殊列表）
			this.length = 1;//缓存该函数值的长度
			return 1;
		}else {//如果为Cons的话则递归
			int len = 1 + ((Cons)(this.another.data)).getLength();
			this.length = len;//缓存该函数值的长度
			return len;
		}
	}
	
//	public int getLength() {
//		if(this.length == -1 || (JLispType.CONS == this.another.type && ((Cons)(this.another.data)).length == -1)) {//-1代表长度值还没有被缓存进新值
//			this.length = getConsLength();
//			return this.length;
//		}else {
//			return this.length;
//		}
//	}
	
	public int getLength() {
		
		if(!(JLispType.CONS == this.another.type)) {//如果这个列表的右值不为Cons的话，则该Cons的长度为1，
			//（不是2，因为右值为nil的时候这个Cons才是一个列表，长度为1，或者右值为其它不是Cons类型的值的时候其长度同样为1，只不过是特殊列表）
//			this.length = 1;//缓存该函数值的长度
			return 1;
		}else {//如果为Cons的话则递归
			int len = 1 + ((Cons)(this.another.data)).getLength();
//			this.length = len;//缓存该函数值的长度
			return len;
		}
	}
	
	/*
	 * 清除该列表及所有下级列表的长度缓存值
	 */
	public void flushConsLength() {
		this.length = -1;
		if(JLispType.CONS == this.another.type) {
			((Cons)(this.another.data)).flushConsLength();
		}
	}
	
	public void setItemById(int id, JLispData value) {
		/*if(JLispType.ATOM != value.type) {
			new Error("The closure item must be an atom");
			return;
		}*/
		if(id < 0 || id >= this.getLength()) {
			new Error("Can not set the index of this cons,Because of IndexOutOfBoundsError");
			return;
		}
		if(id == 0) {
			this.val = value;
		}else {
			((Cons)(this.getRestById(id).data)).val = value;
		}
		
	}
	/*
	 * 该函数表示根据索引值获取列表中剩余的列表，如0则获取到的是列表本身，1获取到下一级列表
	 */
	public JLispData getRestById(int id) {
		if(id < 0 || id >= this.getLength()) {
			return new JLispData(new Error("Can not get Rest from \""+this.toString()+"\" Cons,Because of IndexOutOfBoundsError"), JLispType.ERROR);
		}
		if(id == 0) {
			//一般情况下不能从一个列表中取出索引值为0的剩余的列表，因为这个列表就是自己，这种情况下会额外地包装一层JLispData造成不必要的封装（一定有现成的JLispData供使用）
			//所以这里会给一个警告
			new Error("The data that index of cons is 0 was encapsulated unnecessarry");
			return new JLispData(this, JLispType.CONS);
		}
		if(id == 1) {
			return this.another;
		}else {
			return ((Cons)(this.another.data)).getRestById(id - 1);
		}
	}
	/*
	 * 函数表示根据索引值获取该列表中的元素
	 */
	public JLispData getItemById(int id) {
		int len = getLength();//获取该列表的长度
		if(id < 0 || id >= len) {//如果id小于0或者大于等于这个列表的长度则返回Error，例如不能取出长度为3的(a b c)列表中索引值为3或大于3的元素，也不能取出索引值为-1等小于0的元素
			return new JLispData(new Error("Can not get Item from \""+this.toString()+"\" Cons,Because of IndexOutOfBoundsError"), JLispType.ERROR);
		}
		if(id == 0) {//如果索引值为0，则代表获取该列表的左值
			return this.val;
		}else {//如果索引值大于零则采用递归的方法，即要获取当前列表的第num个元素，则只需获取当前列表的子列表（右值）的第num-1个元素
//			Cons c = (Cons)(this.another.data);
//			return c.getItemById(id - 1);
			return ((Cons)(this.another.data)).getItemById(id - 1);
		}
	}
	
	public int indexOfAtom(Atom atom) {//返回该原子在这个列表中的第几个索引值，如果该原子不在此列表中则返回-1
		if(this.val.data == atom) {
			return 0;
		}
		if(JLispType.CONS == this.another.type) {
			int indexOfNext = ((Cons)(this.another.data)).indexOfAtom(atom);
//			if(indexOfNext == -1) {
//				return -1;
//			}else {
//				return indexOfNext + 1;
//			}
			return indexOfNext == -1 ? -1 : indexOfNext + 1;
		}else {
			return -1;
		}
	}
	
	public Cons clone(Cons cons) {
		if(JLispType.CONS != cons.val.type && JLispType.CONS != cons.another.type) {
			return new Cons(cons.val, cons.another);
		}
		if(JLispType.CONS != cons.val.type && JLispType.CONS == cons.another.type) {
			return new Cons(cons.val, new JLispData(clone(((Cons)(cons.another.data))), JLispType.CONS));
		}
		if(JLispType.CONS == cons.val.type && JLispType.CONS != cons.another.type) {
			return new Cons(new JLispData(clone(((Cons)(cons.val.data))), JLispType.CONS), cons.another);
		}
		if(JLispType.CONS == cons.val.type && JLispType.CONS != cons.another.type) {
			return new Cons(new JLispData(clone(((Cons)(cons.val.data))), JLispType.CONS), new JLispData(clone(((Cons)(cons.another.data))), JLispType.CONS));
		}
		return null;
	}
	
	public JLispData getDeepCons(int deep) {
		if(deep > this.getLength()) {
			return null;
		}
		JLispData returnAns = new JLispData(this, JLispType.CONS);
		for(int i = 0;i < deep;i++) {
			returnAns = ((Cons)(returnAns.data)).another;
		}
		return returnAns;
	}
}